package com.gree.yipai.base;

import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.MotionEvent;
import android.view.inputmethod.InputMethodManager;

import androidx.annotation.RequiresApi;
import androidx.fragment.app.FragmentActivity;

import com.billy.android.swipe.SmartSwipe;
import com.billy.android.swipe.consumer.ActivitySlidingBackConsumer;
import com.gree.yipai.Const;
import com.gree.yipai.YiPaiApp;
import com.gree.yipai.activity.DialogActivity;
import com.gree.yipai.activity.LoginActivity;
import com.gree.yipai.server.APIAction;
import com.gree.yipai.server.bean.IntentKV;
import com.gree.yipai.server.db.DbHelper;
import com.gree.yipai.server.network.async.AsyncTaskManager;
import com.gree.yipai.server.network.async.OnDataListener;
import com.gree.yipai.server.network.http.HttpException;
import com.gree.yipai.server.response2.Respone;
import com.gree.yipai.server.utils.CommonUtils;
import com.gree.yipai.server.utils.FileUtil;
import com.gree.yipai.server.utils.NToast;
import com.gree.yipai.server.utils.SharedPreferencesUtil;
import com.gree.yipai.server.utils.json.JsonMananger;
import com.gree.yipai.service.ListenDataService;
import com.gree.yipai.utils.ActivityCollector;
import com.gree.yipai.utils.DateUtil;

import java.util.Date;


/**
 * 基础Activity
 */
public abstract class BaseActivity
        extends FragmentActivity implements OnDataListener {

    protected Context mContext;
    public AsyncTaskManager mAsyncTaskManager;
    protected APIAction action;
    /**
     * 是否有网
     */
    public boolean onNet ;
    public String ftpDir ;
    public String token;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (Build.VERSION.SDK_INT != Build.VERSION_CODES.O){
            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
        }
        mContext = this ;
            //异步线程、事件相关
        mAsyncTaskManager = AsyncTaskManager.getInstance(getApplicationContext());
        // API接口
        action = new APIAction(mContext);
        DbHelper.getInstance(getApplicationContext());
        token = getData(Const.TOKEN,null);
        if(token!=null){
            action.setToken(token);
        }
        //把ftpdir放到全局去方便使用
        ftpDir = getData(Const.FTP_DIR,"");
        onNet = CommonUtils.isNetworkConnected(mContext);
        ActivityCollector.addActivity(this);
        String haslogin = SharedPreferencesUtil.getData(Const.HASLOGIN, Const.FALSE);
        if(Const.TRUE.equals(haslogin)){
            shouldStartService = true;
        }else{
            shouldStartService = false ;
        }
        if (setEnableSliding()) {
            SmartSwipe.wrap(this)
                    .removeAllConsumers()
                    .addConsumer(new ActivitySlidingBackConsumer(this))
                    .setRelativeMoveFactor(0.5F)
                    .enableLeft()
                    .smoothRightOpen()
                    .smoothClose()
                    .as(ActivitySlidingBackConsumer.class);
        }
    }
    protected boolean setEnableSliding() {
        return true;
    }

    public Boolean shouldStartService;
    @Override
    protected void onResume() {
        super.onResume();
       // NLog.e("shouldStartService",shouldStartService);
        if(shouldStartService) {
           // ExtendTokenService.actionStart(mContext);
            ListenDataService.actionStart(YiPaiApp.getApp());
        }
        if(!DateUtil.checkIsToday()){
            putData(Const.GET_PATCH_COUNT,0);
            loginOut();
        }
        boolean shouldReboot = getData(Const.SHOULD_RELOAD,false);
        if(shouldReboot){
            DialogActivity.shouldReboot(mContext);
        }
    }


    /**
     * 发送请求（需要检查网络）
     *
     * @param requestCode 请求码
     */
    public void request(int requestCode) {
        if (mAsyncTaskManager != null) {
            mAsyncTaskManager.request(requestCode, this);
        }
    }


    /**
     * 发送请求（需要检查网络）
     *
     * @param id 请求数据的用户ID或者groupID
     * @param requestCode 请求码
     */
    public void request(String id , int requestCode) {
        if (mAsyncTaskManager != null) {
            mAsyncTaskManager.request(id, requestCode, this);
        }
    }

    /**
     * 发起请求 并把Uri转为path
     * @param uri
     * @param requestCode
     */
    public void request(Uri uri,int requestCode){
        String filepath = FileUtil.getPath(mContext,uri);
        request(filepath,requestCode);
    }

    /**
     * 发送请求
     *
     * @param requestCode    请求码
     * @param isCheckNetwork 是否需检查网络，true检查，false不检查
     */
    public void request(int requestCode, boolean isCheckNetwork) {
        if (mAsyncTaskManager != null) {
            mAsyncTaskManager.request(requestCode, isCheckNetwork, this);
        }
    }

    /**
     * 取消所有请求
     */
    public void cancelRequest() {
        if (mAsyncTaskManager != null) {
            mAsyncTaskManager.cancelRequest();
        }
    }


    @Override
    public Object doInBackground(int requestCode, String id) throws HttpException {

        return null;
    }

    private int errCount = 0 ;

    @Override
    public void onSuccess(final int requestCode, Object result) {
        if(result instanceof Respone){
            Respone respone = (Respone)result;
            if(respone.getStatusCode()==401) {
                errCount++;
                //NLog.e("sdgshsdgg44",errCount);
                Long dates = getData(Const.REFRESH_TOKEN_EXPIRES_TIME,0l);
                if(dates>0){
                    Date date = new Date(dates);
                    //NLog.e("extend_token",DateUtil.format(date,null),new Date().after(date));
                    if(new Date().before(date)){
                        boolean should = putData(Const.SHOULD_REFRESH_TOKEN,false);
                        if(!should){
                            putData(Const.SHOULD_REFRESH_TOKEN,true);
                            new Handler().postDelayed(new Runnable() {
                                @Override
                                public void run() {
                                    request(requestCode);
                                }
                            },2000);
                        }
                    }else{
                        shouldLoginOut();
                    }
                }
            }
        }
    }

    @Override
    public void onFailure(final int requestCode, int state, Object result) {
        if(result instanceof Respone){
            Respone respone = (Respone)result;
            if(respone.getStatusCode()==401) {
                Long dates = SharedPreferencesUtil.getData(Const.REFRESH_TOKEN_EXPIRES_TIME,0l);
                if(dates>0){
                    Date date = new Date(dates);
                    //NLog.e("extend_token",DateUtil.format(date,null),new Date().after(date));
                    if(new Date().before(date)){
                        boolean should = putData(Const.SHOULD_REFRESH_TOKEN,false);
                        if(!should){
                            putData(Const.SHOULD_REFRESH_TOKEN,true);
                            new Handler().postDelayed(new Runnable() {
                                @Override
                                public void run() {
                                    request(requestCode);
                                }
                            },2000);
                        }
                    }else{
                        shouldLoginOut();
                    }
                }
            }
        }
        //做些请求失败的处理，如果不想用这些处理方式可以在子类中不使用super.onFailure
        switch (state) {
            case AsyncTaskManager.REQUEST_CREATE_CODE:
                shortToast( "创建成功");
                break;
            case AsyncTaskManager.REQUEST_DATA_ERROR_CODE:
                shortToast( "提交数据不合法,请检查");
                break;
            case AsyncTaskManager.REQUEST_FORBIDDEN_CODE:
                shortToast( "无权限访问");
                break;
            case AsyncTaskManager.REQUEST_NOTPAGE_CODE:
                shortToast( "当前API接口已失效");
                break;
           case AsyncTaskManager.REQUEST_DECODE_CODE:
                shortToast( "数据解析异常！");
                break;
            case AsyncTaskManager.HTTP_TIMEOUT_CODE:
                shortToast( "网络请求超时，请重试!");
                break;
            case AsyncTaskManager.REQUEST_ERROR_CODE:
                shortToast( "网络请求异常，请重试！");
                break;
            case AsyncTaskManager.RESPONE_ERROR_CODE:
                shortToast( "很抱歉当前服务器故障，请稍后重试！");
                break;
            case AsyncTaskManager.HTTP_ERROR_CODE:
                shortToast( "网络请求异常，请重试!");
                break;
            case AsyncTaskManager.HTTP_NULL_CODE:
                shortToast( "当前网络不可用");
                break;
        }
        if(result instanceof Exception){
            Exception e = (Exception)result;
            Log.e("onFailure",requestCode+"/"+e.getMessage());
        }
    }





    //是否有网
    public boolean isNetConnected(){
        return onNet;
    }
    /**
     * 退出
     */
    public void loginOut(){
        //清空任务栈
        startActivity(LoginActivity.class);
        ActivityCollector.finishAll();
    }

    //强制退出
    public void shouldLoginOut(){
        //清空任务栈
        startActivity(LoginActivity.class, IntentKV.set("您的账号登录因网络原因或在其他地方修改了密码导致掉线，为保证账号安全请您重新登录!"));
        ActivityCollector.finishAll();
    }

    @Override
    public void onBackPressed() {
        super.onBackPressed();
    }

    /**
     * 提示
     * @param msg
     */
    public void shortToast(String msg){
        NToast.shortToast(mContext,msg);
    }

    public void longToast(String msg){
        NToast.longToast(mContext,msg);
    }

    /**
     *
     * @param json
     * @param cls
     * @param <T>
     * @return
     */
    public static <T> T jsonToBean(String json, Class<T> cls) {
        try {
            return JsonMananger.jsonToBean(json,cls);
        }catch (Exception e){
            Log.e("jsonToBean",e.getMessage());
        }
        return null;
    }

    /**
     *
     * @param obj
     * @return
     * @throws HttpException
     */
    public static String beanToJson(Object obj){
        try {
            return JsonMananger.beanToJson(obj);
        }catch (Exception e){
            Log.e("beanToJson",e.getMessage());
        }
        return null;
    }


    @RequiresApi(api = Build.VERSION_CODES.CUPCAKE)
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (null != this.getCurrentFocus() && event.getAction() == MotionEvent.ACTION_UP) {
            InputMethodManager mInputMethodManager = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
            return mInputMethodManager.hideSoftInputFromWindow(this.getCurrentFocus().getWindowToken(), 0);
        }
        return super.onTouchEvent(event);
    }


    /**
     * 打开并关闭当前
     * @param cla
     * @param obj
     */
    public void startActivityAndFinish(Class cla,Object ...obj){
        startActivity(cla,obj);
        finish();
    }
    private long times;
    /**
     * 打开页面
     * @param cla
     * @param obj 参数名称ext_{i},intentKV 只能传int float String
     */
    public void startActivity(Class cla,Object ...obj){
        if(System.currentTimeMillis()-times<=1000){
            return;
        }
        times = System.currentTimeMillis();
        //防止点击太快打开多个页面
        Intent intent = CommonUtils.getIntent(obj);
        intent.setClass(this,cla);
        this.startActivity(intent);
    }

    /**
     * 打开有回调的页面
     * @param cla
     * @param requestCode
     * @param obj 参数名称ext_{i},intentKV 只能传int float String
     */
    public void startActivityWidthResult(Class cla, int requestCode, Object ...obj){
        if(System.currentTimeMillis()-times<=1000){
            return;
        }
        times = System.currentTimeMillis();
        Intent intent = CommonUtils.getIntent(obj);
        intent.setClass(this,cla);
        startActivityForResult(intent,requestCode);
    }



    /**
     * 简单存取数据
     * @param key
     * @param value
     * @return
     */
    public boolean putData(String key,Object value){
        return SharedPreferencesUtil.putData(key,value);
    }
    public <T extends Object>T getData(String key,Object value){
        return (T) SharedPreferencesUtil.getData(key,value);
    }

    protected void onPause() {
        super.onPause();
        if(isFinishing()){
            //time = System.currentTimeMillis();
            ActivityCollector.removeActivity(this);
            //NLog.e("onDestroy","开始回收内存...");
        }
    }
   // private long time;
    @Override
    protected void onDestroy() {
        super.onDestroy();
        //NLog.e("onDestroy","回收内存资源耗时:"+(System.currentTimeMillis() - time)+"ms");
    }

    /**
     * 设置全局字体大小
     * @return
     */
    //重写字体缩放比例 api<25
    @Override
    public Resources getResources() {
        Resources res =super.getResources();
        if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.N) {
            Configuration config = res.getConfiguration();
            config.fontScale= YiPaiApp.getApp().getFontScale();//1 设置正常字体大小的倍数
            res.updateConfiguration(config,res.getDisplayMetrics());
        }
        return res;
    }
    //重写字体缩放比例  api>25
    @Override
    protected void attachBaseContext(Context newBase) {
        if(Build.VERSION.SDK_INT>Build.VERSION_CODES.N){
            final Resources res = newBase.getResources();
            final Configuration config = res.getConfiguration();
            config.fontScale= YiPaiApp.getApp().getFontScale();//1 设置正常字体大小的倍数
            final Context newContext = newBase.createConfigurationContext(config);
            super.attachBaseContext(newContext);
        }else{
            super.attachBaseContext(newBase);
        }
    }

}
